package com.soso.j.spider.ocr;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

/**
 * 灰度公式是 gray = 0.212671 * R + 0.715160 * G + 0.072169 * B
 * gray大于128，为白色，小于，为黑色
 * @author www.02ta.com
 *
 */
public class OcrTest {
	
	private static Map<String,String> map=new HashMap<String, String>();
	
	static{
		//新蛋价格OCR模板
		
		map.put("111111", ".");
		map.put("00011001110111111111100110001100011000110001100011000110001100011", "1");
		map.put("00111100011111101100001111000011000000110000011100001110000111000011100001110000011000001111111111111111", "2");
		map.put("00111100011111100110011011000111000001100001110000011110000001110000001111000011111000110111111000111100", "3");
		map.put("000000110000001110000011110000011110000110110001100110001000110011000110011111111111111111000000110000000110000000110", "4");
		map.put("00111110011111110110000001100000011111000111111011000011000000110000001100000011110001110111111000111100", "5");
		map.put("00011100011111100110001111000000110111001111111011100011110000111100001111000011011000110111111000111100", "6");
		map.put("11111111111111110000011000000110000011000001110000011000000110000011000000110000001100000011000000100000", "7");
		map.put("00111100011111101110001111000011111001100111111000111110110001111100001111000011111000110111111000111100", "8");
		map.put("00111100011111101100011011000011110000111100001111000111011111110011101100000011110001100111111000111000", "9");
		map.put("00111100011111100110011011000011110000111100001111000011110000111100001111000011011001100111111000111100", "0");
		
		
		//京东价格OCR模板
		
		map.put("111111", ".");
		map.put("001100111100001100001100001100001100001100001100001100001100111111", "1");
		map.put("011111100110000110110000011000000011000000110000001100000011000000110000001100000011000000111111111", "2");
		map.put("011111100110000110110000011000000011000000110000111100000000110000000011110000011110000110011111100", "3");
		map.put("00000011000000011100000010110000010011000010001100010000110010000011001111111111000000110000000011000000001100", "4");
		map.put("011111111011000000011000000011000000011111100000000110000000011000000011110000011110000110011111100", "5");
		map.put("000111110001100000011000000110000000110111100111000110110000011110000011110000011011000110001111100", "6");
		map.put("111111111000000011000000110000000110000001100000001100000011000000011000000110000000110000001100000", "7");
		map.put("001111100011000110110000011110000011011000110001111100011000110110000011110000011011000110001111100", "8");
		map.put("001111100011000110110000011110000011110000011011000111001111011000000011000000110000001100011111000", "9");
		map.put("001111100011000110110000011110000011110000011110000011110000011110000011110000011011000110001111100", "0");
		
	}
	/**
	 * 测试
	 * @throws IOException 
	 */
	public static void main(String args[]) throws IOException {
		String urlString="http://price.360buyimg.com/gp1004119067,3.png";
		URL url = new URL(urlString);
		HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
		InputStream in = urlConnection.getInputStream();
		//FileInputStream in=new FileInputStream("D:/test/gp1004499573,3.png");
		
		byte[] imageInByte = readByByte(in);
		
		List<String> list=readTemp(imageInByte);
		//print(list);
		System.out.print(recognition(list,60));
	}
	
	/**
	 * 识别数字
	 * @param list
	 * @return
	 */
	public static String recognition(List<String> list, int rate){
		String result="";
		for(String str:list){
			str=str.replaceAll("\r\n", "");
			if(map.containsKey(str)){
				String v=map.get(str);
				result+=v;
				//System.out.println(v);
			}else{
				int maxRate=0;
				String v="";
				for(String temp:map.keySet()){
					int t=Distance.similarRate(temp, str);
					if(t>maxRate){
						maxRate=t;
						v=map.get(temp);
						//System.out.println(v+">"+maxRate);
					}
					
				}
				if(maxRate>rate){
					//System.out.println(v);
					result+=v;
				}
			}
		}
		return result;
	}
	
	/**
	 * 打印矩阵
	 * @param list
	 */
	public static void print(List<String> list){
		for(String str:list){
			System.out.println(str.replaceAll("0", " "));
			System.out.println(str.replaceAll("\r\n", ""));
			System.out.println("");
		}
	}
	
	/**
	 * 转换到黑白单色位图
	 * @param srcImg
	 * @param width
	 * @param height
	 * @return
	 */
	public static int[] convertToBlackWhite(final BufferedImage srcImg, final int width, final int height){
        int[] pixels = new int[width * height];
        srcImg.getRGB(0, 0, width, height, pixels, 0, width);
        int newPixels[] = new int[width * height];
        for(int i = 0; i < width * height; i++) {
            int r = (pixels[i] >> 16) & 0xff;
            int g = (pixels[i] >> 8) & 0xff;
            int b = (pixels[i]) & 0xff;
            // Gray=R×0.299+G×0.587+B×0.114
            int gray = (int)(0.189  * r + 0.587 * g + 0.114 * b);
            if(gray>128){
            	newPixels[i]=-1;//0x00ffffff;白色
            }else{
            	//newPixels[i]= (gray<<16)+ (gray<<8)+ gray;
            	newPixels[i]= 0xff000000;//黑色
            }
        }
        return newPixels;
    }
	
	/**
	 * 读取每个数字的矩阵
	 * @param imageInByte
	 * @return
	 * @throws IOException
	 */
	public static List<String> readTemp(byte[] imageInByte) throws IOException{
		List<String> list=new ArrayList<String>();
		InputStream in = new ByteArrayInputStream(imageInByte);
		BufferedImage image = ImageIO.read(in);
		int iw = image.getWidth();
		int ih = image.getHeight();
		int pixels[] =convertToBlackWhite(image, iw, ih) ;
        int matrix[][]=new int[ih][iw];
        int x=0;
        int y=0;
		for (int i=0,len=pixels.length;i<len;i++) {
			matrix[y][x]=pixels[i];
			if((i+1)%iw==0){
				y++;
				x=0;
			}else{
				x++;
			}
		}
		boolean isSplit=true;
		boolean isEmpty=true;
		int n=0;
		int t=0;
		int maxWidth=0;
		int maxHeight=0;
		int nmatrix[][][]=new int[10][ih][iw];
		for (int i=0;i<iw;i++) {
			isSplit=true;
			for (int j=0;j<ih;j++) {
				nmatrix[n][j][t]=matrix[j][i];
				if (matrix[j][i] != -1){
					isSplit=false;
				}
			}
			t++;
			if(isSplit){
				if(!isEmpty){
					StringBuffer sb=new StringBuffer();
					int height=read(sb, nmatrix[n], ih, iw, maxWidth);
					if(height>maxHeight){
						maxHeight=height;
					}
					list.add(sb.toString());
					n++;
					isEmpty=true;
				}
				t=0;
			}else{
				maxWidth=t;
				isEmpty=false;
			}
		}
		return list;
	}
	
	public static int read(StringBuffer sb, int [][] matrix, int ih, int iw, int maxWidth){
		int height=0;
		for (int i=0;i<ih;i++) {
			boolean isEmpty=true;
			String temp="";
			for (int j=0;j<maxWidth;j++) {
				if (matrix[i][j] == -1 || matrix[i][j] == 0){
					temp+="0";
				} else{
					isEmpty=false;
					temp+="1";
				}
			}
			if(isEmpty){
				continue;
			}
			height++;
			sb.append(temp);
			sb.append("\r\n");
		}
		return height;
	}
	
	public static byte[] readByByte(InputStream inStream) throws IOException { 
        ByteArrayOutputStream outstream = new ByteArrayOutputStream(); 
        byte[] buffer = new byte[1024];
        int len = -1; 
        while ((len = inStream.read(buffer)) != -1) { 
            outstream.write(buffer, 0, len); 
        }
        outstream.close(); 
        return outstream.toByteArray();
    } 
}
